package edu.uwm.capstone.diasmart.database;

import java.util.ArrayList;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class SubTypeDAO {

	private static long DEFAULT_SUB_TYPE_ID = -1L;
	private static final String ORDER_BY_FIELDS = "type_id,user_order,sub_type";
	private static final String SELECT_FIELDS;
	private DatabaseHelper dbh;

	static {
		StringBuilder localStringBuilder = new StringBuilder();
		localStringBuilder.append("_id,type_id,sub_type,is_default");
		localStringBuilder.append(",unit,user_order,user_default");
		SELECT_FIELDS = localStringBuilder.toString();
	}

	public SubTypeDAO(DatabaseHelper databaseHelper) {
		this.dbh = databaseHelper;
	}

	private SubType createSubType(Cursor paramCursor) {
		long id = paramCursor.getLong(0);
		int typeID = paramCursor.getInt(1);
		String name = paramCursor.getString(2);
		boolean isDefault = false, isUserDefault = false;
		String unit = paramCursor.getString(4);
		int userOrder = paramCursor.getInt(5);
		if (paramCursor.getInt(3) == 1)
			isDefault = true;

		if (paramCursor.getInt(6) != 1)
			isUserDefault = true;

		return new SubType(id, typeID, name, isDefault, unit, userOrder,
				isUserDefault);

	}

	private void setContentValues(SubType subType, ContentValues newContent) {
		newContent.put("type_id", Integer.valueOf(subType.getTypeId()));
		newContent.put("sub_type", subType.getName());
		newContent.put("unit", subType.getUnit());
		newContent.put("user_order", Integer.valueOf(subType.getUserOrder()));

		if (subType.isDefault())
			newContent.put("is_default", Integer.valueOf(1));
		else if (!subType.isDefault())
			newContent.put("is_default", Integer.valueOf(0));

		if (subType.isUserDefault())
			newContent.put("user_default", Integer.valueOf(1));
		else if (subType.isUserDefault())
			newContent.put("user_default", Integer.valueOf(0));

	}

	public SubType getDefaultSubType() {
		Cursor result = this.dbh.getReadableDatabase().rawQuery(
				"SELECT " + SELECT_FIELDS + " from " + "sub_types" + " where "
						+ "is_default" + " = 1", null);
		try {
			if (result.move(1)) {
				SubType localSubType = createSubType(result);
				return localSubType;
			}
		} finally {
			if (result != null)
				result.close();
		}
		if (result != null)
			result.close();
		return null;
	}

	public long getDefaultSubTypeId() {
		if (DEFAULT_SUB_TYPE_ID < 0L)
			DEFAULT_SUB_TYPE_ID = getDefaultSubType().getId();
		return DEFAULT_SUB_TYPE_ID;
	}

	public SubType getSubType(long id) {
		Cursor result = this.dbh.getReadableDatabase().rawQuery(
				"SELECT " + SELECT_FIELDS + " from " + "sub_types" + " where "
						+ "_id" + " = " + id, null);
		try {
			if (result.move(1)) {
				SubType localSubType = createSubType(result);
				return localSubType;
			}
		} finally {
			if (result != null)
				result.close();
		}
		if (result != null)
			result.close();
		return null;
	}

	public SubType[] getSubTypes() {
		ArrayList<SubType> subTypeList = new ArrayList<SubType>();
		Cursor result = this.dbh.getReadableDatabase().rawQuery(
				"SELECT " + SELECT_FIELDS + " from " + "sub_types"
						+ " order by " + ORDER_BY_FIELDS, null);
		try {
			while (result.move(1)) {
				subTypeList.add(createSubType(result));
			}
			return (SubType[]) subTypeList.toArray(new SubType[subTypeList
					.size()]);
		} finally {
			result.close();
		}
	}

	public SubType[] getSubTypes(int typeId) {
		ArrayList<SubType> subTypeList = new ArrayList<SubType>();
		Cursor result = this.dbh.getReadableDatabase().rawQuery(
				"SELECT " + SELECT_FIELDS + " from " + "sub_types" + " where "
						+ "type_id" + " = " + typeId + " order by "
						+ ORDER_BY_FIELDS, null);
		try {
			while (result.move(1)) {
				subTypeList.add(createSubType(result));
			}
			return (SubType[]) subTypeList.toArray(new SubType[subTypeList
					.size()]);
		} finally {
			result.close();
		}
	}

	public SubType[] getSubTypesUsed(int typeId, long minEntryTime,
			long maxEntryTime) {
		ArrayList<SubType> subTypeList = new ArrayList<SubType>();
		Cursor result = this.dbh.getReadableDatabase().rawQuery(
				"SELECT DISTINCT " + SELECT_FIELDS + " from " + "sub_types"
						+ " where " + "_id" + " in (" + "select DISTINCT "
						+ "sub_type_id" + " from " + "entries" + " where "
						+ "type_id" + "=" + typeId + " AND " + "entry_time"
						+ ">=" + minEntryTime + " and " + "entry_time" + "<="
						+ maxEntryTime + ")" + " order by " + ORDER_BY_FIELDS,
				null);
		try {
			while (result.move(1)) {
				subTypeList.add(createSubType(result));
			}
			return (SubType[]) subTypeList.toArray(new SubType[subTypeList
					.size()]);
		} finally {
			if (result != null)
				result.close();
		}
	}

	public boolean subTypeExists(String subType) {
		Cursor result = this.dbh.getReadableDatabase().rawQuery(
				"SELECT _id FROM sub_types WHERE sub_type='" + subType + "'",
				null);
		try {
			boolean bool = result.move(1);
			return bool;
		} finally {
			result.close();
		}
	}

	public void insert(SQLiteDatabase db, SubType subType) {
		ContentValues newContent = new ContentValues();
		setContentValues(subType, newContent);
		subType.setId(db.insert("sub_types", null, newContent));
		subType.setModified(false);
	}

	public void delete(long id) {
		this.dbh.getEntryDAO().updateSubType(id, getDefaultSubTypeId());
		this.dbh.getWritableDatabase().delete("sub_types", "_id=" + id, null);
	}

	public void delete(SubType subType) {
		delete(subType.getId());
	}

	private void update(SQLiteDatabase db, SubType subType) {
		ContentValues newContent = new ContentValues();
		setContentValues(subType, newContent);
		db.update("sub_types", newContent, "_id=" + subType.getId(), null);
		subType.setModified(false);
	}

	public void save(SubType subType) {
		if (!subType.isModified())
			;

		if (subType.getId() > 0L)
			insert(this.dbh.getWritableDatabase(), subType);
		while (!subType.isUserDefault()) {
			this.dbh.getWritableDatabase().execSQL(
					"UPDATE sub_types SET user_default=0 WHERE _id<>"
							+ subType.getId() + " AND " + "type_id" + "="
							+ subType.getTypeId());
			update(this.dbh.getWritableDatabase(), subType);
		}

	}

}
